package com.caifu.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;

@Configuration
public class shiroConfig {

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    @Bean(name = "sessionDAO")
    public MemorySessionDAO getMemorySessionDAO() {
        return new MemorySessionDAO();
    }

    @Bean(name = "sessionIdCookie")
    public SimpleCookie getSimpleCookie() {
        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setName("SHRIOSESSIONID");
        return simpleCookie;
    }

    //将自己的验证方式加入容器
    @Bean
    public CustomRealm myShiroRealm() {
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }

    //配置shiro session 的一个管理器
    @Bean(name = "sessionManager")
    public DefaultWebSessionManager getDefaultWebSessionManager(@Qualifier("sessionDAO") MemorySessionDAO sessionDAO,
                                                                @Qualifier("sessionIdCookie") SimpleCookie simpleCookie) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionDAO(sessionDAO);
        sessionManager.setSessionIdCookie(simpleCookie);
        return sessionManager;
    }

    //配置session的缓存管理器
    @Bean(name = "shiroCacheManager")
    public MemoryConstrainedCacheManager getMemoryConstrainedCacheManager() {
        return new MemoryConstrainedCacheManager();
    }

    //权限管理，配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager(
            @Qualifier("shiroCacheManager") MemoryConstrainedCacheManager shiroCacheManager,
            @Qualifier("sessionManager") DefaultWebSessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setCacheManager(shiroCacheManager);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }


    //Filter工厂，设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //Map<String, String> map = new HashMap<>();
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        //登出
        map.put("/logout", "anon");
        map.put("/authentication", "anon");
        map.put("/foodConfirm/**", "anon");
        map.put("/ordering/testPrint", "anon");
        map.put("/common/**", "anon");
        map.put("/**/activity/**", "anon");
        map.put("/**/bmuserinfo/**", "anon");
        map.put("/**/getRecordById/**", "anon");
        map.put("/**/staff/**", "anon");
        map.put("/**/excel/**", "anon");
        map.put("/**/medicine/**", "anon");
        map.put("/**/data/**", "anon");
        map.put("/**/meicinedistribution/**", "anon");
        map.put("/**/healthArchive/**", "anon");
        map.put("/**/msg/**", "anon");
        map.put("/**/bill/**", "anon");
        map.put("/resetPsw", "anon");
        map.put("/resetPswSuc", "anon");
        map.put("/identity", "anon");
        map.put("/changePassword","anon");
        map.put("/static/**", "anon");
        map.put("/templates/**", "anon");
        map.put("/**/user/**", "anon");
        map.put("/**/org/**", "anon");
        map.put("/**/sysRole/**", "anon");
        map.put("/**/userInfo/**", "anon");
        map.put("/**/img/**", "anon");
        map.put("/**/gc/**", "anon");
        map.put("/**/label/**", "anon");
        map.put("/**/404.html", "anon");
        map.put("/**/500.html", "anon");
        map.put("/**/doc.html", "anon");
        map.put("/**/resources/webjars/**", "anon");
        map.put("/**/argsException.html", "anon");
        map.put("/**", "authc");
        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //错误页面，认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }


    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }
}
